<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        // 1.let const var 区别 
        // let 变量 const常量(赋值) 不能改变的(但是如果修改的是对象,可以修改里面的值,因为检测的是堆内存地址的变化)
        // letconst 块级作用域
        // let const 没有变量提升 var 有变量提升 是提升到当前作用域的顶部
        // let num = 2;
        // num++;
        //   const nums=[1,2,3]; 
        //   nums=[]

        // if(true){
        //     var num=10;
        //     console.log(num)
        // };
        // console.log("外面",num)

        // function fn(){
        //     console.log(nums) 
        //     let nums=10;
        // }
        // fn();
        // console.log("外面",nums)
        // console.log("外面",nums)

        // 2.解构赋值
    //  对象的解构赋值  是key值对应之后.给value变量设置值
    //  数组的解构赋值  是按照位置对应之后.给value变量设置值
        // let {b:b,a:a,c:c}={a:1,b:2,c:3};
        // // console.log(a,b,c)
    
        // let {a:a,b:e,f:c}={a:1,b:2,c:3};
        // // a 1
        // // b 没有定义
        // // c undefined 
        // // e  2
        // // f 未定义 not defined
        // console.log(a)
        // // console.log(b)
        // console.log(c)
        // console.log(e)
        // console.log(f)

        // queryParams={username:"zhangsan",age:18};
       
        // getUserByparams({username,age}){

        // }

        // getUserByparams(queryParams)


//         function foo() {
//             console.log("参数",Array.from(arguments))
//             setTimeout(function(...reset){
//             console.log(this)

//                 console.log('id:', this.id);
//             }, 100);
//             }

//             var id = 21;
// // foo()
// // call apply bind 改变this指向. 箭头函数不能改变
// // apply   a开头  array  参数传数组
//             foo.call({ id: 42 }, 1, 2, 3);
//             // foo.apply({ id: 42 });
//         // arguments  参数集合

// // 数组的方法  
// var arr1 = ["su",1,29,1,23,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20];
// // Array.from  // 类数组转数组
// Array.from(new Set(arr1));
// [...new Set(arr1)]

// console.log(arr1.find((item)=>{return item>10})) // 找到第一个满足条件的元素
// console.log(arr1.findIndex((item)=>{return item>10})) // 找到第一个满足条件的元的下标
// console.log(arr1.findLast((item)=>{return item>10})) // 从后往前找到第一个满足条件的元素
// console.log(arr1.findLastIndex((item)=>{return item>10})) // 从后往前找到第一个满足条件的元素的下标

// console.log(arr1.filter((item)=>{return item>10})) // 找到所有满足条件的元素
// var newarr = arr1.map((item)=>{return item>10}) //map方法  对数组中的每个元素进行函数处理.返回一个新数组
// console.log("newarr",newarr) 
// console.log(arr1.some((item)=>{return item>10})) // 找到第一个满足条件的元素 只要有就是true
// console.log(arr1.every((item)=>{return item>10})) // 找到所有满足条件的元素 只要有一个不满足就是false

// arr1.includes(1) // 判断数组中是否包含某个元素
// // flat   扁平化数组
// var arr2 = [2,3,[4,5,[6,7]]]
// console.log(arr2.flat(1))  // 扁平化数组  扁平化几层
// console.log(arr2.flat(Infinity))  // 扁平化数组  扁平化几层
// // 自己可以在原型上添加方法 判断元素是不是数组.如果是数组就调用自身.如果不是数组就push到新数组中
// Array.prototype.myflat = function(){
//     var newarr = [];
//     for(var i=0;i<this.length;i++){
//         if(Array.isArray(this[i])){
//             newarr = newarr.concat(this[i].myflat())
//         }else{
//             newarr.push(this[i])
//         }
//     } 
//     return newarr;
// }
// // splice方法给数组进行增删改 (下标,删除的个数,增加的元素) 
// var arr3 = [5,7,6,9,10] //  ===> [5,7,6,11,12,13,10] 
// arr3.splice(3,1,11,12,13) 
// // 改变原数组方法 7个   push pop shift unshift splice reverse sort   vue2源码里面.就改写了这7个
// // reduce 方法  对数组中的每个元素进行函数处理.返回一个新数组
// var sumcount=arr3.reduce((pre,cur,index,arr3)=>{
//     console.log(pre,cur)
//     return pre+cur
// },2) // 0 是初始值
// console.log(sumcount)
// // console.log(arr2.myflat())
// // splice  reduce 

// // 对象的新增方法
// Object.assign({a:1,b:2},{c:3,d:4,a:8}) // 合并对象     浅拷贝

// const obj1 = {c:3,a: {b: 1}};
// const obj2 = Object.assign({}, obj1);

// obj1.a.b = 2;
// console.log(obj2.a.b) // 2

// // 佚名 
// var message = {
//     body: {
     
//     }
//   };

// // 错误的写法
// // const  firstName1 = message.body.user.firstName || '佚名';
// // console.log(firstName1)
// // 正确的写法
// // const firstName = (message
// //   && message.body
// //   && message.body.user
// //   && message.body.user.firstName) || '佚名';
// // ?.链式运算符判断的是?左侧的是否为undefined或者null 
// // ??是为了取默认值的   它和|| 的区别 || 的前面是只要转化后是false就会取后面的值  ??的前面是只要是undefined或者null就会取后面的值
// // 什么能判断为false呢  0 null undefined '' NaN false  也称为短路运算符
// const  firstName1 = message?.body?.user?.firstName || '佚名';

// console.log(firstName1)
// // 类型的判断
// // typeof 基本类型
// typeof(null) // object
// typeof(undefined); // undefined

// message instanceof Object; // true
// [] instanceof Array; // true


const o = {b:"苏明"}; // 创建一个新对象

// 通过 defineProperty 使用访问器属性描述符添加对象属性的示例
let bValue = 38;
Object.defineProperty(data, "b", {
  get() {
    console.log("访问了b属性");
    return bValue;
  },
  set(newValue) {
    console.log("设置了b属性");
    bValue = newValue;
  },
  enumerable: true,
  configurable: true,
});
// o.b; // 38
o.b = 25; // 设置了b属性
// 'b' 属性存在于对象 o 中，其值为 38。
// o.b 的值现在始终与 bValue 相同，除非重新定义了 o.b。





    </script>

</body>
</html>